import {getLocal } from '@/utils/local'
import store from '../store'
import * as types from '@/store/action_type'

class WS {
  constructor(config = {}) {
    this.url = config.url || 'vue.zhufengpeixun.cn';
    this.port = config.port || 80;
    //protocol是个只读属性，用于返回服务器端选中的子协议的名字；这是一个在创建WebSocket 对象时，在参数protocols中指定的字符串
    this.protocol = config.protocol || 'ws';
    // 心跳检测 证明你还能用 30秒
    this.time = config.time || 30 * 1000;
    this.ws = null;
  }
  onOpen = () => {
    //连接建立，即握手成功触发的事件
    // 规定好发的必须是对象 对象里包含两个字段 type  data
    // websocket 是基于tcp 第一次连接靠的http 但是不能修改header
    this.ws.send(JSON.stringify({
      type: 'auth',
      data: getLocal('token')
    }))
    //收到服务器消息时触发的事件
    onMessage = (e) => {
      let {type, data} = JSON.parse(e.data);
      switch(type) {
        case 'noAuth':
          console.log('没有权限');
          break;
        case 'heartCheck':
          this.checkServer();//触发检查服务器的方法，为了防止断线
          this.ws.send(JSON.stringify({type:'heartCheck'}));
          break;
        default://默认情况下时提交消息
          store.commit(types.SET_MESSAGE,data);
      }
    }
    onError = () => {
      setTimeout(() => {
        this.create(); //重新调用create方法 连线的 
      }, 1000)
    }
    // 关闭连接事件
    onClose = () => {
      this.ws.close();
    }
    create = () => {
      this.ws = new WebSocket(`${this.protocol}://${this.url}:${this.port}`);
      this.ws.onopen = this.onOpen;
      this.ws.onmessage = this.onMessage;
      this.ws.onerror = this.onError;
      this.ws.onclose = this.onClose;
    }
    checkServer = () => { //服务器回应
      clearTimeout(this.timer); // 防抖
      this.timer = setTimeout(() => {
        this.onClose();
        this.onError();
      }, this.time + 1000) // 断线重连
    }
    send = (msg) => {
      this.ws.send(JSON.stringify(msg))
    }
  }
}

export default WS;